package org.taobao.ibatiside.ui.wizard;

import java.beans.PropertyChangeEvent;

import org.eclipse.datatools.connectivity.IConnectionProfile;
import org.eclipse.datatools.sqltools.result.ResultsViewPlugin;
import org.eclipse.datatools.sqltools.result.ui.ResultsViewUIPlugin;
import org.eclipse.datatools.sqltools.result.ui.view.ResultsViewControl;
import org.eclipse.datatools.sqltools.sqlbuilder.IExecuteSQLListener;
import org.eclipse.datatools.sqltools.sqlbuilder.ParseException;
import org.eclipse.datatools.sqltools.sqlbuilder.SQLBuilder;
import org.eclipse.datatools.sqltools.sqlbuilder.input.ISQLBuilderEditorInput;
import org.eclipse.datatools.sqltools.sqlbuilder.input.SQLBuilderEditorInput;
import org.eclipse.datatools.sqltools.sqlbuilder.model.OmitSchemaInfo;
import org.eclipse.datatools.sqltools.sqlbuilder.model.SQLStatementInfo;
import org.eclipse.datatools.sqltools.sqlbuilder.sqlbuilderdialog.ResultsHistoryFilter;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.PartInitException;

public class SqlBuilderPage extends BatisCommonPage implements IExecuteSQLListener {
	CTabFolder _tabFolder;
	CTabItem _tabItemResults;
	SQLBuilder sqlbuilder;
	ResultsViewControl _resultsViewControl;
	ViewerFilter[] _resultViewFilters;
	boolean sqlChanged;
	public SqlBuilderPage() {
		super("sql_builder");
		setTitle("SQL Builder");
		setDescription("Build customed sql in friendly manner!");
	}
	@Override
	public void dispose() {
		sqlbuilder.removeExecuteSQLListener(this);
		ResultsViewPlugin.getDefault().getResultManager()
				.removeResultManagerListener(_resultsViewControl);
		_resultsViewControl.dispose();
		ResultsViewPlugin
				.getDefault()
				.getResultManager()
				.addResultManagerListener(
						new ResultsViewUIPlugin.ResultViewControlListener());
		super.dispose();
	}
	
	@Override
	public IWizardPage getNextPage() {
		return super.getNextPage();
	}
	@Override
	public boolean isPageComplete() {
		return model.getDtpStmt() != null;
	}

	@Override
	public void doCreateControl(Composite parent) {
		Composite main = createFillArea(parent);
		setControl(main);
		_tabFolder = createTabFolder(main, SWT.BOTTOM);
		CTabItem tabEditor = createTabItem(_tabFolder, SWT.NONE, 0,
				"SQL Builder");
		Composite editComposite = createFillArea(_tabFolder);
		createSqlBuilder();
		sqlbuilder.createClient(editComposite);
		sqlbuilder.addExecuteSQLListener(this);
		tabEditor.setControl(editComposite);
		_tabItemResults = createTabItem(_tabFolder, SWT.NONE, 1, "SQL Result");
		Composite resultsComposite = createFillArea(_tabFolder);
		_tabItemResults.setControl(resultsComposite);

		createResultView(resultsComposite);
		_tabFolder.setSelection(tabEditor);
		sqlbuilder.getSourceViewer().getControl().addFocusListener(new FocusAdapter() {
			String init_sql ;
			@Override
			public void focusGained(FocusEvent e) {
				init_sql = sqlbuilder.getSQL();
			}
			@Override
			public void focusLost(FocusEvent e) {
				sqlChanged = !sqlbuilder.getSQL().equals(init_sql);
				getWizard().getContainer().updateButtons();
			}
		});
	}
	@Override
	public boolean canFlipToNextPage() {
		sqlbuilder.reparseIfRequired();
		String last_error = sqlbuilder.getDomainModel().getImproperStatement();
		if (last_error != null)
		{
			setErrorMessage("Wrong SQL, please check it!");
			return false;
		}else{
			setErrorMessage(null);
			if (sqlChanged){
				model.setOpSql(this.sqlbuilder.getSQL());
				model.setDtpStmt(sqlbuilder.getDomainModel().getSQLStatement());
				sqlChanged = false;
			}
			return model.getDtpStmt() != null;
		}
	}
	private void createResultView(Composite resultsComposite) {
		_resultsViewControl = new ResultsViewControl();
		ResultsViewPlugin
				.getDefault()
				.getResultManager()
				.removeResultManagerListener(
						new ResultsViewUIPlugin.ResultViewControlListener());
		ResultsViewPlugin.getDefault().getResultManager()
				.addResultManagerListener(_resultsViewControl);
		/*
		 * Tell the results view to use preferences
		 */
		_resultsViewControl.setUsePreferences(true);
		try {
			_resultsViewControl.init();
		} catch (PartInitException e) {
			System.out.println(e.getLocalizedMessage());
			e.printStackTrace();
		}
		_resultsViewControl.createPartControl(resultsComposite);
		GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true);
		_resultsViewControl.getControl().setLayoutData(gd);

		filterResultsView(model.getConnectionProfile());
	}

	private void filterResultsView(IConnectionProfile connectionProfile) {
		// if no filter is specified, use default filter for specified profile
		// name
		ViewerFilter[] filters = _resultViewFilters;
		if (filters == null || filters.length == 0) {
			filters = new ViewerFilter[] { new ResultsHistoryFilter(
					connectionProfile.getName()) };
		}

		for (int i = 0; i < filters.length; i++) {
			_resultsViewControl.addResultHistoryFilter(filters[i]);
		}
	}

	public SQLBuilder getSqlbuilder() {
		return sqlbuilder;
	}

	protected void setResultViewFilters(ViewerFilter[] filters) {
		_resultViewFilters = filters;
	}

	private void createSqlBuilder() {
		sqlbuilder = new SQLBuilder();
		ISQLBuilderEditorInput input = buildInput();
		try {
			sqlbuilder.setInput(input);
		} catch (PartInitException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}

	private ISQLBuilderEditorInput buildInput() {
		OmitSchemaInfo omitSchemaInfo = new OmitSchemaInfo();
		omitSchemaInfo.initFromPreferences();
		SQLStatementInfo ssi = new SQLStatementInfo(model.getOpSql());
		SQLBuilderEditorInput input = new SQLBuilderEditorInput(model.getConnectionProfile(), ssi, omitSchemaInfo);
		return input;
	}

	private CTabFolder createTabFolder(Composite main, int style) {
		CTabFolder tabFolder = new CTabFolder(main, style);

		GridLayout mainCompLayout = new GridLayout(1, true);
		tabFolder.setLayout(mainCompLayout);

		GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true);
		tabFolder.setLayoutData(gd);

		return tabFolder;
	}

	private Composite createFillArea(Composite parent) {
		Composite mainComposite = new Composite(parent, SWT.NONE);

		GridLayout mainCompLayout = new GridLayout(1, true);
		mainComposite.setLayout(mainCompLayout);

		GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true);
		mainComposite.setLayoutData(gd);

		return mainComposite;
	}

	private CTabItem createTabItem(CTabFolder tabFolder, int style, int tabNum,
			String name) {
		CTabItem tabItem = new CTabItem(tabFolder, style, tabNum);
		tabItem.setText(name);
		return tabItem;
	}

	public void executedSQL() {
		_tabFolder.setSelection(_tabItemResults);
	}
	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		if (BatisSettingModel.K_OP_SQL.equals(evt.getPropertyName())){
			if (evt.getOldValue() == null){
				model.setDtpStmt(sqlbuilder.getDomainModel().getSQLStatement());
			}
		}
	}


}
